from ats.log import logger
from ats.util import keygen
from ats.cache import memcache_mgr
import time

# ------------------------------------------------------------------------------
# Globals 
# ------------------------------------------------------------------------------
log = logger.get_logger()
cache = memcache_mgr.get_cache()
TWENTY_MIN = 60*20 

# ------------------------------------------------------------------------------
# Cookie 
# ------------------------------------------------------------------------------
class Cookie:
	""" This is a simple Cookie impl 
	"""
	__slots__ = "name", "val", "domain", "expires"
	
	def __init__(self, name="", val="", hostname=""):
		self.name = name
		self.val = val
		self.domain = ".".join(hostname.split(".")[-2:]) 
		self.expires = time.asctime(time.gmtime(time.time() + 30*60))

	def __str__(self):
		return """%s=%s; expires=%s; path=/; domain=.%s """ %\
			(self.name, self.val, self.expires, self.domain)

# ------------------------------------------------------------------------------
def parse_cookie(str):
	dict = {}
	fields = str.split("; ")
	for field in fields:
		f = field.split("=")
		dict[f[0]] = f[1]
	return dict

# ------------------------------------------------------------------------------
# Session Object:
# ------------------------------------------------------------------------------
class Session:
	""" AltTechStack Session handling
	"""

	__slots__ = "userid", "skey", "createdt", \
			"lastupdt", "uri", "vars", "host"

	def __init__(self, req):
		self.userid = 0l
		self.skey = ''
		self.uri = req.unparsed_uri
		self.vars = {}
		self.createdt = (long)(time.time()*1000)
		self.lastupdt = self.createdt
		if req and req.headers_in and req.headers_in.has_key('Host'):
			self.host = req.headers_in['Host'] 
		else:
			self.host = ""
		if req and req.headers_in and req.headers_in.has_key('User-Agent'):
			self.useragent = req.headers_in['User-Agent']
		else:
			self.useragent = ""
		if req and req.headers_in and req.headers_in.has_key('Referer'):
			self.referer= req.headers_in['Referer']
		else:
			self.referer = ""

# ------------------------------------------------------------------------------
# Session funcs: 
# ------------------------------------------------------------------------------
def get_session(req, create_one=1):
	"""This function gets the session obj
		and creates one if neccisary.
	"""

	global cache, log
	try: # attempts to retrieve the session obj from the cache 
		if req and req.headers_in and req.headers_in.has_key('Cookie'):
			cookie = parse_cookie(req.headers_in['Cookie'])
			if cookie.has_key('skey') and cookie['skey']:
				session = cache.get('ats.sesh:%s' % cookie['skey'])
				if session:
					req.headers_out["Set-Cookie"] = "%s"\
						% Cookie("skey", session.skey, req.hostname)
					return session

		# create a new one
		if create_one:
			return create_session(req)

		# otherwise return none
		return None
	except Exception, e:
		log.error("sessionmanager.get_session() error: %s" % (e))
		return None

# ------------------------------------------------------------------------------
def persist_session(session):
	""" Saves the session
	"""
	global cache, log
	if session:
		cache.set('ats.sesh:%s' % session.skey, session, TWENTY_MIN) 

# ------------------------------------------------------------------------------
def create_session(req, session=None, num_tries=0):
	"""This function creates the session, then persists 
		it to the cache. 
	"""

	global TWENTY_MIN, cache
	
	# prevent infinate loop
	if num_tries > 10:
		return None

	# create a new session
	if not session:
		session = Session(req)

	# persist the session
	session.skey = keygen.get_key(size=24)
	cache.set('ats.sesh:%s' % session.skey, session, TWENTY_MIN) 
	
	# return the session obj
	if not req.headers_out.has_key("Set-Cookie"):
		req.headers_out["Cache-Control"] = 'no-cache="set-cookie"'
	req.headers_out["Set-Cookie"] = "%s"\
		% Cookie("skey", session.skey, req.hostname)
	return session
